Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check-meta.nix: Add package warnings #338267

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

AkechiShiro
Copy link
Contributor

@AkechiShiro AkechiShiro commented Aug 29, 2024

Description of changes

Implements RFC 127 NixOS/rfcs#127
Adds testing for multiple cases

Should supersede : #177272

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.11 Release Notes (or backporting 23.11 and 24.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@AkechiShiro
Copy link
Contributor Author

I will rebase then work on solving conflicts, marking this PR as draft for now.

@AkechiShiro AkechiShiro marked this pull request as draft August 29, 2024 21:05
pkgs/stdenv/generic/check-meta.nix Outdated Show resolved Hide resolved
piegamesde and others added 2 commits August 30, 2024 08:46
* Also fix merge conflicts
* Make sure that performance PR is conserved
* Use RunCommand instead of alias RunCommandNoCC
* Add enum types to meta-types.nix and use them for problemTypes
* Nixfmt (excepted check-meta.nix)
* "import" elem
* Remove dead code
@AkechiShiro AkechiShiro marked this pull request as ready for review September 4, 2024 12:35
++ lib.optionals (meta ? problems) (

# Check problem kinds are correct
lib.pipe meta.problems [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks very allocation/iteration heavy:
I'd completely avoid using lib.pipe in any hot paths for one.

For a normal code review I wouldn't be so pedantic about this, but check-meta is a performance special case.
Changes here needs to be carefully measured, and the Ofborg performance report doesn't include checkMeta, so it's entirely useless in this context.

Measuring nixpkgs eval with checkMeta = true before and after this PR (env NIX_SHOW_STATS=1 nix-env -qa -f ./outpaths.nix --arg checkMeta true > /dev/null):

  • Before
{
  "cpuTime": 271.2768249511719,
  "envs": {
    "bytes": 7850426888,
    "elements": 413454253,
    "number": 283924554
  },
  "gc": {
    "heapSize": 22804639744,
    "totalBytes": 47139879824
  },
  "list": {
    "bytes": 987373624,
    "concats": 21648163,
    "elements": 123421703
  },
  "nrAvoided": 329081776,
  "nrFunctionCalls": 261979419,
  "nrLookups": 131336801,
  "nrOpUpdateValuesCopied": 675865734,
  "nrOpUpdates": 32046977,
  "nrPrimOpCalls": 146549876,
  "nrThunks": 399878601,
  "sets": {
    "bytes": 15552994336,
    "elements": 911935337,
    "number": 60126809
  },
  "sizes": {
    "Attr": 16,
    "Bindings": 16,
    "Env": 16,
    "Value": 24
  },
  "symbols": {
    "bytes": 2887399,
    "number": 178950
  },
  "values": {
    "bytes": 12350285592,
    "number": 514595233
  }
}
  • After
{
  "cpuTime": 296.9483947753906,
  "envs": {
    "bytes": 8506454064,
    "elements": 438912624,
    "number": 312197067
  },
  "gc": {
    "heapSize": 22737526784,
    "totalBytes": 48902439376
  },
  "list": {
    "bytes": 1000276576,
    "concats": 22264431,
    "elements": 125034572
  },
  "nrAvoided": 349063893,
  "nrFunctionCalls": 289412278,
  "nrLookups": 149742381,
  "nrOpUpdateValuesCopied": 694111348,
  "nrOpUpdates": 35108342,
  "nrPrimOpCalls": 168992563,
  "nrThunks": 417292743,
  "sets": {
    "bytes": 15871244064,
    "elements": 927562812,
    "number": 64389942
  },
  "sizes": {
    "Attr": 16,
    "Bindings": 16,
    "Env": 16,
    "Value": 24
  },
  "symbols": {
    "bytes": 4092168,
    "number": 234982
  },
  "values": {
    "bytes": 12774278736,
    "number": 532261614
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What could be used to have better performance whilst keeping the same or similar functionality ?

Copy link
Member

@adisbladis adisbladis Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Don't keep calling mapAttrsToList
    mapAttrsToList is attrs: map fn (attrNames attrs).
    You should store attrNames in a variable and keep reusing that

  • lib.remove null -> concatMap
    Nix has an optimisation for empty lists

The code below is a good simple example:

# Check that problem has a message (required field)
++ lib.pipe meta.problems [
  (lib.mapAttrsToList (    name: problem:
    if problem ? message then
      null
    else
      "key 'meta.problems.${name}.message' is missing"
    ))
    (lib.remove null)
]

->

let
  # Stick this in the outermost scope where it makes sense
  problemNames = attrNames meta.problems;
in
  # Nix has an optimisation for returning empty lists
  # And another optimisation for lists with <= 2 elements
  concatMap (name: if meta.problems.${name} ? message then [] else [ "key 'meta.problems.${name}.message' is missing" ])

Copy link
Member

@adisbladis adisbladis Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And just in general: Read the lib implementations you're using here and understand that Nix is not very optimised.
Sadly we don't have good guidance on how to write performant Nix code.
NIX_SHOW_STATS=1 is your friend.

# Check that some problem kinds are unqiue
++ lib.pipe meta.problems [
(lib.mapAttrs (name: problem: { kind = name; } // problem))
# Count the number of instances of each problem kind,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the manual counting & checking is better implemented by combining groupBy & concatMap over problemKindsUnique'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants